<template>
  <div class="wrap">
    <aside class="list">
      <h2>视频列表</h2>
      <ul>
        <li v-for="v in videos" :key="v.id"
            :class="{ active: v.id === current?.id }"
            @click="selectVideo(v)">
          <div class="title">{{ v.title }}</div>
          <div class="sub">时长(秒)：{{ v.durationSec || '-' }}</div>
        </li>
      </ul>
    </aside>

    <main class="player">
      <h2 v-if="current">{{ current.title }}</h2>

      <video v-if="playUrl"
             ref="player"
             :src="playUrl"
             controls
             @loadedmetadata="onLoaded"
             @timeupdate="onTick"
             class="video"></video>

      <div v-if="!current" class="placeholder">请选择左侧视频</div>

      <div class="actions" v-if="current">
        <button v-if="!purchased" @click="onBuy" :disabled="buying">
          {{ buying ? '购买中...' : '购买完整视频' }}
        </button>
        <span v-else class="tip">已购买，可完整播放</span>
      </div>
    </main>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { fetchVideoList, fetchPlayUrl, buyVideo } from '@/api/video'

const userId = 1

const videos = ref([])
const current = ref(null)
const player = ref(null)
const playUrl = ref('')
const duration = ref(0)
const purchased = ref(false)
const buying = ref(false)
const LIMIT_RATIO = 0.2
let hasAlerted = false  // 新增：防止重复弹窗

onMounted(async () => {
  videos.value = await fetchVideoList()
})

async function selectVideo(v) {
  current.value = v
  hasAlerted = false

  // 向后端要“当前可播放的URL”
  playUrl.value = await fetchPlayUrl(v.id, userId)

  // 根据是否返回了 fullUrl 来判断是否已购买（不改后端的前提下）
  purchased.value = (playUrl.value === v.fullUrl)

  await nextTick()
  duration.value = 0
}

function onLoaded() {
  duration.value = player.value?.duration ?? 0
}

function onTick() {
  if (!purchased.value && duration.value && player.value) {
    const limit = duration.value * LIMIT_RATIO
    if (player.value.currentTime >= limit) {
      // 避免多次弹窗
      if (!hasAlerted) {
        hasAlerted = true
        alert('试看已结束，请购买后继续播放')
      }
      player.value.currentTime = limit
      player.value.pause()
    }
  }
}

async function onBuy() {
  if (!current.value) return
  try {
    buying.value = true
    const cur = player.value?.currentTime || 0
    await buyVideo(current.value.id, userId)
    // 购买后重新拉取播放URL
    playUrl.value = await fetchPlayUrl(current.value.id, userId)
    purchased.value = (playUrl.value === current.value.fullUrl)
    hasAlerted = false

    await nextTick()
    player.value.onloadedmetadata = () => {
      player.value.currentTime = cur
      player.value.play()
    }
  } catch (e) {
    alert(e.message || '购买失败')
  } finally {
    buying.value = false
  }
}
</script>


<style scoped>
.wrap { display: grid; grid-template-columns: 300px 1fr; gap: 16px; height: 100vh; padding: 16px; box-sizing: border-box; }
.list { border-right: 1px solid #eee; overflow: auto; }
.list ul { list-style: none; padding: 0; margin: 0; }
.list li { padding: 10px; border-bottom: 1px solid #f2f2f2; cursor: pointer; }
.list li.active { background: #f7faff; }
.title { font-weight: 600; }
.sub { color: #888; font-size: 12px; margin-top: 4px; }
.player { padding: 0 8px; display: flex; flex-direction: column; }
.video { width: 100%; max-height: calc(100vh - 200px); background: #000; }
.actions { margin-top: 12px; }
.placeholder { color: #888; margin-top: 60px; }
button { padding: 8px 14px; }
.tip { color: #2e7d32; font-weight: 600; }
</style>


